<template>
  <div>
    <el-button type="primary" @click="dialogVisible = true">加载本地文件</el-button>
    <el-dialog title="Load JSON document from file" :visible.sync="dialogVisible">
      <el-upload :file-list="uploadFiles" action="alert" :auto-upload="false" multiple :on-change="loadJsonFromFile">
        <el-button size="small" type="primary">选择文件</el-button>
        <div slot="tip">上传文件小于500MB</div>
      </el-upload>
      <span slot="footer">
        <el-button type="primary" @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="loadJsonFromFileConfirmed">确定</el-button>
      </span>
    </el-dialog>
    <input v-model="search" type="text" />

    <div @click="handleClickJson">
      <json-viewer ref="jsonViewer" class="my-awesome-json-theme" sort v-if="json" :value="json" :expand-depth=5
        copyable boxed>
      </json-viewer>

    </div>
  </div>
</template>

<script>

export default {

  data() {
    return {
      // data for upload files
      uploadFilename: null,
      uploadFiles: [],
      dialogVisible: false,
      json: {
        "currm_content": {
          "cell_info": {
            "cell_index": 2,
            "cellm_cell_state": "CELLM_CELL_STATE_ACTIVE",
            "current_stop_adm_flag": "NONE",
            "current_ue_num": 0,
            "max_ue_num": 0,
            "mif_cell_state": "MIF_CELL_STATE_NONE",
            "mobility_algo": "RRM_NR_LTE_DISABLE",
            "nci": 8639922434,
            "ns_group": [],
            "operator_group": [],
            "operator_id": 0,
            "plmn": "46000",
            "prb_threshold_unit": 0,
            "share_strategy": "RRM_RAN_SHRING_STRATEGY_NONE",
            "ssb_freq": 504990,
            "ue_admission_failure_cause": "FAIL_CAUSE_NONE"
          },
          "diaglog": [],
          "fd_info": {
            "fd_cause": "CURRM_INNER_CAUSE_MATCH_NEIGHBOR_FAIL",
            "fd_id": "RRM_HO_FAIL",
            "fd_procedure": "HANDOVER",
            "fd_type": "CURRM_FAIL_CURRM_PARSE_OR_CHECK_FAIL"
          },
          "match_neighbor_event": {
            "time": "2022-10-24 10:15:02.342"
          },
          "ongoing_measure_result": {
            "meas_id": 2,
            "measure_purpose": "RRM_INTRA_A3_MEAS_CONFIG",
            "neighbor_pci_list": [],
            "rsrp": [],
            "ssb_freq": 504990
          },
          "ongoing_pdu_info": [],
          "ue_info": {
            "establishment_cause": "RRC_ESTAB_CAUSE_NONE",
            "tmsi": 0,
            "ue_index": 3451,
            "ue_measure_state": "RRM_MEAS_STATE_IDLE",
            "ue_nssai_list": [
              16777216
            ],
            "ue_state": "RRM_UE_WAIT_FOR_MEAS_CONFIG_RESP"
          }
        },
        "general": {
          "cellid": 258,
          "gnbid": 2109356,
          "module": "MODULE_CURRM",
          "time": "2022-10-24 10:15:02.342",
          "ueid": 3451
        }
      }
      ,
      search: ""
    }
  },
  watch: {
    search: {
      deep: true,
      immediate: true,
      handler(n) {
        if (n) {
          console.log(n);
          // this.tools(this.json, [n])
          if (this.$refs.jsonViewer) {
            [n] = [n].map(item => item = `${item}:`)
            console.log([n]);
            this.getNodes(document.querySelector(".my-awesome-json-theme"), [n])
          }
        }
      }
    },
  },

  methods: {
    loadJsonFromFile(file, fileList) {
      this.uploadFilename = file.name
      this.uploadFiles = fileList
    },
    // 前端预读取文件内容
    loadJsonFromFileConfirmed() {
      console.log(this.uploadFiles)
      if (this.uploadFiles) {
        for (let i = 0; i < this.uploadFiles.length; i++) {
          let file = this.uploadFiles[i]
          console.log(file.raw)
          if (!file) continue
          let reader = new FileReader()
          reader.onload = async (e) => {
            try {
              let document = JSON.parse(e.target.result)
              console.log(document)
              this.json = document
            } catch (err) {
              console.log(`加载文件失败: ${err.message}`)
              this.showSnackbar(`加载文件失败: ${err.message}`, 4000)
            }
          }
          reader.readAsText(file.raw)
        }
      }
      this.dialogVisible = false
    },
    handleClickJson() {
      setTimeout(() => {
        let temp = [this.search].map(item => item = `${item}:`)
        this.getNodes(
          document.querySelector(".my-awesome-json-theme"),
          temp
        );
      }, 10);
    },
    // 递归改变对象的key  创建一个新的的key(需要结构防止指向同一个对象导致被删除),删除原有的key
    tools(obj, arr) {
      let that = this
      function foo(obj, arr) {
        for (const key in obj) {
          if (Object.prototype.toString.call(obj[key]) === "[object Object]") {
            if (arr.includes(key)) {
              that.$set(obj, `${key}【关键字段】`, { ...obj[key] });
              delete obj[key]
              foo(obj[`${key}【关键字段】`], arr);
            } else {
              foo(obj[key], arr);
            }
          } else if (Object.prototype.toString.call(obj[key]) === "[object Array]") {
            if (arr.includes(key)) {
              that.$set(obj, `${key}【关键字段】`, [...obj[key]]);
              delete obj[key]
              obj[`${key}【关键字段】`].forEach(item => {
                foo(item, arr);
              })
            } else {
              obj[key].forEach(item => {
                foo(item, arr);
              })
            }
          } else {
            if (arr.includes(key)) {
              that.$set(obj, `${key}【关键字段】`, obj[key]);
              delete obj[key]
            }
          }
        }


      }
      foo(obj, arr);
    },
    // 直接采用正则字符串替换,dom节点被改变失去原有的功能
    test() {
      console.log(' ', 1111)
      function find(searchVal, bgColor) {
        let oDiv = document.querySelector(".my-awesome-json-theme");
        let sText = oDiv.innerHTML;
        let reg1 = /<script[^>]*>(.|\n)*<\/script>/gi; //去掉script标签
        sText = sText.replace(reg1, "");
        bgColor = bgColor || "orange";
        let sKey = "<span name='addSpan' style='background-color: " + bgColor + ";'>" + searchVal + "</span>";
        let num = -1;
        let rStr = new RegExp(searchVal, "g");
        let rHtml = new RegExp("\<.*?\>", "ig");//匹配html元素
        let aHtml = sText.match(rHtml); //存放html元素的数组
        sText = sText.replace(rHtml, '{~}');  //替换html标签
        sText = sText.replace(rStr, sKey); //替换key
        sText = sText.replace(/{~}/g, function () {  //恢复html标签
          num++;
          return aHtml[num];
        });
        oDiv.innerHTML = sText;
        console.log("sText", sText);
      }

      find('cell_info')
      find('mif_cell_state')

    },
    //工具函数递归改变节点信息,对象太复杂递会归占用大量内存，或者栈溢出
    getNodes(nodeEl, values) {
      function foo(nodeEl, values) {
        if (values.includes(nodeEl.innerText)) {
          nodeEl.style.color = "#Fff"
          nodeEl.style.background = 'orange'
        }
        for (let i = 0; i < nodeEl.childNodes.length; i++) {
          foo(nodeEl.childNodes[i], values);
        }
      }
      foo(nodeEl, values);
    },

  }
}
</script>

<style lang="less" scoped >
.search {
  color: orange;
}

.my-awesome-json-theme {

  background: #fff;
  white-space: nowrap;
  color: #525252;
  font-size: 14px;
  font-family: Consolas, Menlo, Courier, monospace;
  text-align: left;

  .jv-ellipsis {
    color: #999;
    background-color: #eee;
    display: inline-block;
    line-height: 0.9;
    font-size: 0.9em;
    padding: 0px 4px 2px 4px;
    border-radius: 3px;
    vertical-align: 2px;
    cursor: pointer;
    user-select: none;
  }

  .jv-button {
    color: #49b3ff
  }

  .jv-key {
    color: #111111
  }

  .jv-item {
    &.jv-array {
      color: #111111
    }

    &.jv-boolean {
      color: #fc1e70
    }

    &.jv-function {
      color: #067bca
    }

    &.jv-number {
      color: #fc1e70
    }

    &.jv-number-float {
      color: #fc1e70
    }

    &.jv-number-integer {
      color: #fc1e70
    }

    &.jv-object {
      color: #111111
    }

    &.jv-undefined {
      color: #e08331
    }

    &.jv-string {
      color: #42b983;
      word-break: break-word;
      white-space: normal;
    }
  }

  .jv-code {
    .jv-toggle {
      &:before {
        padding: 0px 2px;
        border-radius: 2px;
      }

      &:hover {
        &:before {
          background: #eee;
        }
      }
    }
  }
}
</style>
